home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 January: Mac OS SDK / Dev.CD Jan 99 SDK1.toast / Development Kits / Interfaces&Libraries / Universal / Interfaces / CIncludes / PEFBinaryFormat.h < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-17  |  50.1 KB  |  1,154 lines  |  [TEXT/MPS ]

  1. /*
  2.      File:        PEFBinaryFormat.h
  3.  
  4.      Contains:    PEF Types and Macros
  5.  
  6.      Version:    Technology:    Master Interfaces
  7.                  Release:    Universal Interfaces 3.2
  8.  
  9.      Copyright:    © 1993-1998, 1998 by Apple Computer, Inc., all rights reserved.
  10.  
  11.      Bugs?:        For bug reports, consult the following page on
  12.                  the World Wide Web:
  13.  
  14.                      http://developer.apple.com/bugreporter/
  15.  
  16. */
  17.  
  18.  
  19. #ifndef __PEFBINARYFORMAT__
  20. #define __PEFBINARYFORMAT__
  21.  
  22. #ifndef __MACTYPES__
  23. #include <MacTypes.h>
  24. #endif
  25.  
  26.  
  27.  
  28. #if PRAGMA_ONCE
  29. #pragma once
  30. #endif
  31.  
  32. #ifdef __cplusplus
  33. extern "C" {
  34. #endif
  35.  
  36. #if PRAGMA_IMPORT
  37. #pragma import on
  38. #endif
  39.  
  40. #if PRAGMA_STRUCT_ALIGN
  41.     #pragma options align=mac68k
  42. #elif PRAGMA_STRUCT_PACKPUSH
  43.     #pragma pack(push, 2)
  44. #elif PRAGMA_STRUCT_PACK
  45.     #pragma pack(2)
  46. #endif
  47.  
  48.  
  49.  
  50. /* -------------------------------------------------------------------------------------------- */
  51. /* Almost all types are padded for natural alignment.  However the PEFExportedSymbol type is    */
  52. /* 10 bytes long, containing two 32 bit fields and one 16 bit field.  Arrays of it must be        */
  53. /* packed, so it requires "68K" alignment.  Setting this globally to 68K should also help        */
  54. /* ensure consistent treatment across compilers.                                                */
  55.  
  56.  
  57.  
  58. /* ======================================================================================== */
  59. /* Overall Structure */
  60. /* ================= */
  61.  
  62.  
  63.  
  64. /* -------------------------------------------------------------------------------------------- */
  65. /* This header contains a complete set of types and macros for dealing with the PEF executable    */
  66. /* format.  While some description is provided, this header is not meant as a primary source    */
  67. /* of documentation on PEF.  An excellent specification of PEF can be found in the Macintosh    */
  68. /* Runtime Architectures book.  This header is primarily a physical format description.  Thus    */
  69. /* it depends on as few other headers as possible and structure fields have obvious sizes.        */
  70. /*                                                                                                 */
  71. /* The physical storage for a PEF executable is known as a "container".  This refers to just    */
  72. /* the executable itself, not the file etc.  E.g. if five DLLs are packaged in a single file's    */
  73. /* data fork, that one data fork has five containers within it.                                    */
  74. /*                                                                                                 */
  75. /* A PEF container consists of an overall header, followed by one or more section headers,        */
  76. /* followed by the section name table, followed by the contents for the sections.  Some kinds    */
  77. /* of sections have specific internal representation.  The "loader" section is the most common    */
  78. /* of these special sections.  It contains information on the exports, imports, and runtime        */
  79. /* relocations required to prepare the executable.  PEF containers are self contained, all        */
  80. /* portions are located via relative offsets.                                                    */
  81. /*                                                                                                 */
  82. /*                                                                                                 */
  83. /*            +-------------------------------+                                                    */
  84. /*            |        Container Header        |    40 bytes                                        */
  85. /*            +-------------------------------+                                                    */
  86. /*            |        Section 0 header        |    28 bytes each                                    */
  87. /*            |...............................|                                                    */
  88. /*            |            - - - -                |                                                    */
  89. /*            |...............................|                                                    */
  90. /*            |        Section n-1 header        |                                                    */
  91. /*            +-------------------------------+                                                    */
  92. /*            |        Section Name Table        |                                                    */
  93. /*            +-------------------------------+                                                    */
  94. /*            |        Section x raw data        |                                                    */
  95. /*            +-------------------------------+                                                    */
  96. /*             |            - - - -                |                                                    */
  97. /*            +-------------------------------+                                                    */
  98. /*            |        Section y raw data        |                                                    */
  99. /*            +-------------------------------+                                                    */
  100. /*                                                                                                 */
  101. /*                                                                                                 */
  102. /* The sections are implicitly numbered from 0 to n according to the order of their headers.    */
  103. /* The headers of the instantiated sections must precede those of the non-instantiated            */
  104. /* sections.  The ordering of the raw data is independent of the section header ordering.        */
  105. /* Each section header contains the offset for that section's raw data.                            */
  106.  
  107.  
  108.  
  109. /* =========================================================================================== */
  110. /* Container Header */
  111. /* ================ */
  112.  
  113.  
  114.  
  115.  
  116. struct PEFContainerHeader {
  117.     OSType                             tag1;                        /* Must contain 'Joy!'.*/
  118.     OSType                             tag2;                        /* Must contain 'peff'.  (Yes, with two 'f's.)*/
  119.     OSType                             architecture;                /* The ISA for code sections.  Constants in CodeFragments.h.*/
  120.     UInt32                             formatVersion;                /* The physical format version.*/
  121.     UInt32                             dateTimeStamp;                /* Macintosh format creation/modification stamp.*/
  122.     UInt32                             oldDefVersion;                /* Old definition version number for the code fragment.*/
  123.     UInt32                             oldImpVersion;                /* Old implementation version number for the code fragment.*/
  124.     UInt32                             currentVersion;                /* Current version number for the code fragment.*/
  125.     UInt16                             sectionCount;                /* Total number of section headers that follow.*/
  126.     UInt16                             instSectionCount;            /* Number of instantiated sections.*/
  127.     UInt32                             reservedA;                    /* Reserved, must be written as zero.*/
  128. };
  129. typedef struct PEFContainerHeader        PEFContainerHeader;
  130.  
  131. enum {
  132.     kPEFTag1                    = FOUR_CHAR_CODE('Joy!'),        /* For non-Apple compilers: 0x4A6F7921.*/
  133.     kPEFTag2                    = FOUR_CHAR_CODE('peff'),        /* For non-Apple compilers: 0x70656666.*/
  134.     kPEFVersion                    = 0x00000001
  135. };
  136.  
  137.  
  138.  
  139. enum {
  140.     kPEFFirstSectionHeaderOffset = sizeof(PEFContainerHeader)
  141. };
  142.  
  143. #define PEFFirstSectionNameOffset(container)    \
  144.             ( kPEFFirstSectionHeaderOffset + ((container)->sectionCount * sizeof ( PEFSectionHeader )) )
  145.  
  146.  
  147.  
  148. /* =========================================================================================== */
  149. /* Section Headers */
  150. /* =============== */
  151.  
  152.  
  153.  
  154.  
  155. struct PEFSectionHeader {
  156.     SInt32                             nameOffset;                    /* Offset of name within the section name table, -1 => none.*/
  157.     UInt32                             defaultAddress;                /* Default address, affects relocations.*/
  158.     UInt32                             totalLength;                /* Fully expanded size in bytes of the section contents.*/
  159.     UInt32                             unpackedLength;                /* Size in bytes of the "initialized" part of the contents.*/
  160.     UInt32                             containerLength;            /* Size in bytes of the raw data in the container.*/
  161.     UInt32                             containerOffset;            /* Offset of section's raw data.*/
  162.     UInt8                             sectionKind;                /* Kind of section contents/usage.*/
  163.     UInt8                             shareKind;                    /* Sharing level, if a writeable section.*/
  164.     UInt8                             alignment;                    /* Preferred alignment, expressed as log 2.*/
  165.     UInt8                             reservedA;                    /* Reserved, must be zero.*/
  166. };
  167. typedef struct PEFSectionHeader            PEFSectionHeader;
  168.  
  169. enum {
  170.                                                                 /* Values for the sectionKind field.*/
  171.                                                                 /*    Section kind values for instantiated sections.*/
  172.     kPEFCodeSection                = 0,                            /* Code, presumed pure & position independent.*/
  173.     kPEFUnpackedDataSection        = 1,                            /* Unpacked writeable data.*/
  174.     kPEFPackedDataSection        = 2,                            /* Packed writeable data.*/
  175.     kPEFConstantSection            = 3,                            /* Read-only data.*/
  176.     kPEFExecDataSection            = 6,                            /* Intermixed code and writeable data.*/
  177.                                                                 /* Section kind values for non-instantiated sections.*/
  178.     kPEFLoaderSection            = 4,                            /* Loader tables.*/
  179.     kPEFDebugSection            = 5,                            /* Reserved for future use.*/
  180.     kPEFExceptionSection        = 7,                            /* Reserved for future use.*/
  181.     kPEFTracebackSection        = 8                                /* Reserved for future use.*/
  182. };
  183.  
  184.  
  185.  
  186. enum {
  187.                                                                 /* Values for the shareKind field.*/
  188.     kPEFProcessShare            = 1,                            /* Shared within a single process.*/
  189.     kPEFGlobalShare                = 4,                            /* Shared across the entire system.*/
  190.     kPEFProtectedShare            = 5                                /* Readable across the entire system, writeable only to privileged code.*/
  191. };
  192.  
  193.  
  194.  
  195.  
  196. /* =========================================================================================== */
  197. /* Packed Data Contents */
  198. /* ==================== */
  199.  
  200.  
  201.  
  202. /* -------------------------------------------------------------------------------------------- */
  203. /* The raw contents of a packed data section are a sequence of byte codes.  The basic format    */
  204. /* has a 3 bit opcode followed by a 5 bit count.  Additional bytes might be used to contain        */
  205. /* counts larger than 31, and to contain a second or third count.  Further additional bytes        */
  206. /* contain actual data values to transfer.                                                        */
  207. /*                                                                                                 */
  208. /* All counts are represented in a variable length manner.  A zero in the initial 5 bit count    */
  209. /* indicates the actual value follows.  In this case, and for the second and third counts, the    */
  210. /* count is represented as a variable length sequence of bytes.  The bytes are stored in big    */
  211. /* endian manner, most significant part first.  The high order bit is set in all but the last    */
  212. /* byte.  The value is accumulated by shifting the current value up 7 bits and adding in the    */
  213. /* low order 7 bits of the next byte.                                                            */
  214.  
  215.  
  216.  
  217. enum {
  218.                                                                 /* The packed data opcodes.*/
  219.     kPEFPkDataZero                = 0,                            /* Zero fill "count" bytes.*/
  220.     kPEFPkDataBlock                = 1,                            /* Block copy "count" bytes.*/
  221.     kPEFPkDataRepeat            = 2,                            /* Repeat "count" bytes "count2"+1 times.*/
  222.     kPEFPkDataRepeatBlock        = 3,                            /* Interleaved repeated and unique data.*/
  223.     kPEFPkDataRepeatZero        = 4                                /* Interleaved zero and unique data.*/
  224. };
  225.  
  226.  
  227.  
  228. enum {
  229.     kPEFPkDataOpcodeShift        = 5,
  230.     kPEFPkDataCount5Mask        = 0x1F,
  231.     kPEFPkDataMaxCount5            = 31,
  232.     kPEFPkDataVCountShift        = 7,
  233.     kPEFPkDataVCountMask        = 0x7F,
  234.     kPEFPkDataVCountEndMask        = 0x80
  235. };
  236.  
  237.  
  238. #define PEFPkDataOpcode(byte) ( ((UInt8)(byte)) >> kPEFPkDataOpcodeShift )
  239.  
  240. #define PEFPkDataCount5(byte) ( ((UInt8)(byte)) & kPEFPkDataCount5Mask )
  241.  
  242. #define PEFPkDataComposeInstr(opcode,count5)        \
  243.             ( (((UInt8)(opcode)) << kPEFPkDataOpcodeShift) | ((UInt8)(count5)) )
  244.  
  245.  
  246.  
  247. /* -------------------------------------------------------------------------------------------- */
  248. /* The following code snippet can be used to input a variable length count.                        */
  249. /*                                                                                                 */
  250. /*        count = 0;                                                                                */
  251. /*        do {                                                                                    */
  252. /*            byte = *bytePtr++;                                                                    */
  253. /*            count = (count << kPEFPkDataVCountShift) | (byte & kPEFPkDataVCountMask);            */
  254. /*        } while ( (byte & kPEFPkDataVCountEndMask) != 0 );                                        */
  255. /*                                                                                                 */
  256. /* The following code snippet can be used to output a variable length count to a byte array.    */
  257. /* This is more complex than the input code because the chunks are output in big endian order.    */
  258. /* Think about handling values like 0 or 0x030000.                                                */
  259. /*                                                                                                 */
  260. /*        count = 1;.                                                                                */
  261. /*        tempValue = value >> kPEFPkDataCountShift;                                                */
  262. /*        while ( tempValue != 0 ) {                                                                */
  263. /*            count += 1;                                                                            */
  264. /*            tempValue = tempValue >> kPEFPkDataCountShift;                                        */
  265. /*        }                                                                                        */
  266. /*                                                                                                 */
  267. /*        bytePtr += count;                                                                        */
  268. /*        tempPtr = bytePtr - 1;                                                                    */
  269. /*        *tempPtr-- = value;        // ! No need to mask, only the low order byte is stored.        */
  270. /*        for ( count -= 1; count != 0; count -= 1 ) {                                            */
  271. /*            value = value >> kPEFPkDataCountShift;                                                */
  272. /*            *tempPtr-- = value | kPEFPkDataCountEndMask;                                        */
  273. /*        }                                                                                        */
  274.  
  275.  
  276.  
  277. /* =========================================================================================== */
  278. /* Loader Section */
  279. /* ============== */
  280.  
  281.  
  282.  
  283. /* -------------------------------------------------------------------------------------------- */
  284. /* The loader section contains information needed to prepare the code fragment for execution.    */
  285. /* This includes this fragment's exports, the import libraries and the imported symbols from    */
  286. /* each library, and the relocations for the writeable sections.                                */
  287. /*                                                                                                 */
  288. /*            +-----------------------------------+                <-- containerOffset --------+    */
  289. /*            |        Loader Info Header            |    56 bytes                                |    */
  290. /*            |-----------------------------------|                                            |    */
  291. /*            |        Imported Library 0            |    24 bytes each                            |    */
  292. /*            |...................................|                                            |    */
  293. /*            |            - - -                    |                                            |    */
  294. /*            |...................................|                                            |    */
  295. /*            |        Imported Library l-1        |                                            |    */
  296. /*            |-----------------------------------|                                            |    */
  297. /*            |        Imported Symbol 0            |    4 bytes each                            |    */
  298. /*            |...................................|                                            |    */
  299. /*            |            - - -                    |                                            |    */
  300. /*            |...................................|                                            |    */
  301. /*            |         Imported Symbol i-1            |                                            |    */
  302. /*            |-----------------------------------|                                            |    */
  303. /*            |        Relocation Header 0            |    12 bytes each                            |    */
  304. /*            |...................................|                                            |    */
  305. /*            |            - - -                    |                                            |    */
  306. /*            |...................................|                                            |    */
  307. /*            |        Relocation Header r-1        |                                            |    */
  308. /*            |-----------------------------------|                <-- + relocInstrOffset -----|    */
  309. /*            |        Relocation Instructions        |                                            |    */
  310. /*            |-----------------------------------|                <-- + loaderStringsOffset --|    */
  311. /*            |        Loader String Table            |                                            |    */
  312. /*            |-----------------------------------|                <-- + exportHashOffset -----+    */
  313. /*            |        Export Hash Slot 0            |    4 bytes each                                */
  314. /*            |...................................|                                                */
  315. /*            |            - - -                    |                                                */
  316. /*            |...................................|                                                */
  317. /*            |         Export Hash Slot h-1        |                                                */
  318. /*            |-----------------------------------|                                                */
  319. /*            |        Export Symbol Key 0            |    4 bytes each                                */
  320. /*            |...................................|                                                */
  321. /*            |            - - -                    |                                                */
  322. /*            |...................................|                                                */
  323. /*            |        Export Symbol Key e-1        |                                                */
  324. /*            |-----------------------------------|                                                */
  325. /*            |        Export Symbol 0                |    10 bytes each                                */
  326. /*            |...................................|                                                */
  327. /*            |            - - -                    |                                                */
  328. /*            |...................................|                                                */
  329. /*            |        Export Symbol e-1            |                                                */
  330. /*            +-----------------------------------+                                                */
  331.  
  332.  
  333.  
  334.  
  335. struct PEFLoaderInfoHeader {
  336.     SInt32                             mainSection;                /* Section containing the main symbol, -1 => none.*/
  337.     UInt32                             mainOffset;                    /* Offset of main symbol.*/
  338.     SInt32                             initSection;                /* Section containing the init routine's TVector, -1 => none.*/
  339.     UInt32                             initOffset;                    /* Offset of the init routine's TVector.*/
  340.     SInt32                             termSection;                /* Section containing the term routine's TVector, -1 => none.*/
  341.     UInt32                             termOffset;                    /* Offset of the term routine's TVector.*/
  342.     UInt32                             importedLibraryCount;        /* Number of imported libraries.  ('l')*/
  343.     UInt32                             totalImportedSymbolCount;    /* Total number of imported symbols.  ('i')*/
  344.     UInt32                             relocSectionCount;            /* Number of sections with relocations.  ('r')*/
  345.     UInt32                             relocInstrOffset;            /* Offset of the relocation instructions.*/
  346.     UInt32                             loaderStringsOffset;        /* Offset of the loader string table.*/
  347.     UInt32                             exportHashOffset;            /* Offset of the export hash table.*/
  348.     UInt32                             exportHashTablePower;        /* Export hash table size as log 2.  (Log2('h'))*/
  349.     UInt32                             exportedSymbolCount;        /* Number of exported symbols.  ('e')*/
  350. };
  351. typedef struct PEFLoaderInfoHeader        PEFLoaderInfoHeader;
  352.  
  353.  
  354. /* =========================================================================================== */
  355. /* Imported Libraries */
  356. /* ------------------ */
  357.  
  358.  
  359.  
  360. struct PEFImportedLibrary {
  361.     UInt32                             nameOffset;                    /* Loader string table offset of library's name.*/
  362.     UInt32                             oldImpVersion;                /* Oldest compatible implementation version.*/
  363.     UInt32                             currentVersion;                /* Current version at build time.*/
  364.     UInt32                             importedSymbolCount;        /* Imported symbol count for this library.*/
  365.     UInt32                             firstImportedSymbol;        /* Index of first imported symbol from this library.*/
  366.     UInt8                             options;                    /* Option bits for this library.*/
  367.     UInt8                             reservedA;                    /* Reserved, must be zero.*/
  368.     UInt16                             reservedB;                    /* Reserved, must be zero.*/
  369. };
  370. typedef struct PEFImportedLibrary        PEFImportedLibrary;
  371.  
  372. enum {
  373.                                                                 /* Bits for the PEFImportedLibrary options field.*/
  374.     kPEFWeakImportLibMask        = 0x40,                            /* The imported library is allowed to be missing.*/
  375.     kPEFInitLibBeforeMask        = 0x80                            /* The imported library must be initialized first.*/
  376. };
  377.  
  378.  
  379.  
  380.  
  381. /* =========================================================================================== */
  382. /* Imported Symbols */
  383. /* ---------------- */
  384.  
  385.  
  386.  
  387. /* -------------------------------------------------------------------------------------------- */
  388. /* The PEFImportedSymbol type has the following bit field layout.                                */
  389. /*                                                                                                 */
  390. /*                                                                       3                        */
  391. /*         0             7 8                                             1                        */
  392. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  393. /*      | symbol class  | offset of symbol name in loader string table  |                        */
  394. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  395. /*        |<-- 8 bits --->|<-- 24 bits ---------------------------------->|                        */
  396.  
  397.  
  398.  
  399.  
  400. struct PEFImportedSymbol {
  401.     UInt32                             classAndName;
  402. };
  403. typedef struct PEFImportedSymbol        PEFImportedSymbol;
  404.  
  405. enum {
  406.     kPEFImpSymClassShift        = 24,
  407.     kPEFImpSymNameOffsetMask    = 0x00FFFFFF,
  408.     kPEFImpSymMaxNameOffset        = 0x00FFFFFF                    /* 16,777,215*/
  409. };
  410.  
  411. #define PEFImportedSymbolClass(classAndName)        ((UInt8) ((classAndName) >> kPEFImpSymClassShift))
  412. #define PEFImportedSymbolNameOffset(classAndName)    ((classAndName) & kPEFImpSymNameOffsetMask)
  413.  
  414. #define PEFComposeImportedSymbol(class,nameOffset)        \
  415.             ( ( ((UInt32)(class)) << kPEFImpSymClassShift ) | ( (UInt32)(nameOffset) ) )
  416.  
  417.  
  418. enum {
  419.                                                                 /* Imported and exported symbol classes.*/
  420.     kPEFCodeSymbol                = 0x00,
  421.     kPEFDataSymbol                = 0x01,
  422.     kPEFTVectorSymbol            = 0x02,
  423.     kPEFTOCSymbol                = 0x03,
  424.     kPEFGlueSymbol                = 0x04,
  425.     kPEFUndefinedSymbol            = 0x0F,
  426.     kPEFWeakImportSymMask        = 0x80
  427. };
  428.  
  429.  
  430.  
  431.  
  432. /* =========================================================================================== */
  433. /* Exported Symbol Hash Table */
  434. /* -------------------------- */
  435.  
  436.  
  437.  
  438. /* -------------------------------------------------------------------------------------------- */
  439. /* Exported symbols are described in four parts, optimized for speed of lookup.  These parts    */
  440. /* are the "export hash table", the "export key table", the "export symbol table", and the        */
  441. /* "export name table".  Overall they contain a flattened representation of a fairly normal        */
  442. /* hashed symbol table.                                                                            */
  443. /*                                                                                                */
  444. /* The export hash table is an array of small fixed size elements.  The number of elements is    */
  445. /* a power of 2.  A 32 bit hash word for a symbol is converted into an index into this array.    */
  446. /* Each hash slot contains a count of the number of exported symbols that map to this slot and    */
  447. /* the index of the first of those symbols in the key and symbol tables.  Of course some hash    */
  448. /* slots will have a zero count.                                                                */
  449. /*                                                                                                */
  450. /* The key and symbol tables are also arrays of fixed size elements, one for each exported        */
  451. /* symbol.  Their entries are grouped by hash slot, those elements mapping to the same hash        */
  452. /* slot are contiguous.  The key table contains just the full 32 bit hash word for each            */
  453. /* exported symbol.  The symbol table contains the offset of the symbol's name in the string    */
  454. /* table and other information about the exported symbol.                                        */
  455. /*                                                                                                */
  456. /* To look up an export you take the hashword and compute the hash slot index.  You then scan    */
  457. /* the indicated portion of the key table for matching hashwords.  If a hashword matches, you    */
  458. /* look at the corresponding symbol table entry to find the full symbol name.  If the names        */
  459. /* match the symbol is found.                                                                    */
  460.  
  461.  
  462.  
  463. /* -------------------------------------------------------------------------------------------- */
  464. /* The following function may be used to compute the hash table size.  Signed values are used    */
  465. /* just to avoid potential code generation overhead for unsigned division.                        */
  466. /*                                                                                                 */
  467. /*        UInt8    PEFComputeHashTableExponent    ( SInt32    exportCount )                            */
  468. /*        {                                                                                        */
  469. /*            SInt32    exponent;                                                                    */
  470. /*                                                                                                 */
  471. /*            const SInt32    kExponentLimit        = 16;    // Arbitrary, but must not exceed 30.    */
  472. /*            const SInt32    kAverageChainLimit    = 10;    // Arbitrary, for space/time tradeoff.    */
  473. /*                                                                                                 */
  474. /*            for ( exponent = 0; exponent < kExponentLimit; exponent += 1 ) {                    */
  475. /*                if ( (exportCount / (1 << exponent)) < kAverageChainLimit ) break;                */
  476. /*            }                                                                                    */
  477. /*                                                                                                 */
  478. /*            return exponent;                                                                    */
  479. /*                                                                                                 */
  480. /*        }    // PEFComputeHashTableExponent ()                                                    */
  481.  
  482.  
  483.  
  484. /* -------------------------------------------------------------------------------------------- */
  485. /* The PEFExportedSymbolHashSlot type has the following bit field layout.                        */
  486. /*                                                                                                 */
  487. /*                                   1 1                                 3                        */
  488. /*         0                         3 4                                 1                        */
  489. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  490. /*        | symbol count              | index of first export key         |                        */
  491. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  492. /*        |<-- 14 bits -------------->|<-- 18 bits ---------------------->|                        */
  493.  
  494.  
  495.  
  496.  
  497. struct PEFExportedSymbolHashSlot {
  498.     UInt32                             countAndStart;
  499. };
  500. typedef struct PEFExportedSymbolHashSlot PEFExportedSymbolHashSlot;
  501.  
  502. enum {
  503.     kPEFHashSlotSymCountShift    = 18,
  504.     kPEFHashSlotFirstKeyMask    = 0x0003FFFF,
  505.     kPEFHashSlotMaxSymbolCount    = 0x00003FFF,                    /*  16,383*/
  506.     kPEFHashSlotMaxKeyIndex        = 0x0003FFFF                    /* 262,143*/
  507. };
  508.  
  509. #define PEFHashTableIndex(fullHashWord,hashTablePower)    \
  510.             ( ( (fullHashWord) ^ ((fullHashWord) >> (hashTablePower)) ) & ((1 << (hashTablePower)) - 1) )
  511.  
  512. #define PEFHashSlotSymbolCount(countAndStart)    ((UInt32) ((countAndStart) >> kPEFHashSlotSymCountShift))
  513. #define PEFHashSlotFirstKey(countAndStart)        ((countAndStart) & kPEFHashSlotFirstKeyMask)
  514.  
  515. #define PEFComposeExportedSymbolHashSlot(symbolCount,firstKey)    \
  516.             ( ( ((UInt32)(symbolCount)) << kPEFHashSlotSymCountShift ) | ( (UInt32)(firstKey) ) )
  517.  
  518.  
  519.  
  520. /* =========================================================================================== */
  521. /* Exported Symbol Hash Key */
  522. /* ------------------------ */
  523.  
  524.  
  525.  
  526.  
  527. struct PEFSplitHashWord {
  528.     UInt16                             nameLength;
  529.     UInt16                             hashValue;
  530. };
  531. typedef struct PEFSplitHashWord            PEFSplitHashWord;
  532.  
  533. struct PEFExportedSymbolKey {
  534.     union {
  535.         UInt32                             fullHashWord;
  536.         PEFSplitHashWord                 splitHashWord;
  537.     }                                 u;
  538. };
  539. typedef struct PEFExportedSymbolKey        PEFExportedSymbolKey;
  540.  
  541. enum {
  542.     kPEFHashLengthShift            = 16,
  543.     kPEFHashValueMask            = 0x0000FFFF,
  544.     kPEFHashMaxLength            = 0x0000FFFF                    /* 65,535*/
  545. };
  546.  
  547. #define PEFHashNameLength(fullHashWord)    ((UInt32) ((fullHashWord) >> kPEFHashLengthShift))
  548. #define PEFHashValue(fullHashWord)    ((fullHashWord) & kPEFHashValueMask)
  549.  
  550. #define PEFComposeFullHashWord(nameLength,hashValue)    \
  551.             ( ( ((UInt32)(nameLength)) << kPEFHashLengthShift ) | ( (UInt32)(hashValue) ) )
  552.  
  553.  
  554.  
  555. /* ---------------------------------------------------------------------------------------------------- */
  556. /* The following function computes the full 32 bit hash word.                                            */
  557. /*                                                                                                         */
  558. /*        UInt32    PEFComputeHashWord    ( BytePtr    nameText,        // ! First "letter", not length byte.    */
  559. /*                                      UInt32    nameLength )    // ! The text may be zero terminated.    */
  560. /*        {                                                                                                */
  561. /*            BytePtr    charPtr        = nameText;                                                                */
  562. /*            SInt32    hashValue    = 0;        // ! Signed to match old published algorithm.                */
  563. /*            UInt32    length        = 0;                                                                    */
  564. /*            UInt32    limit;                                                                                */
  565. /*            UInt32    result;                                                                                */
  566. /*            UInt8    currChar;                                                                            */
  567. /*                                                                                                         */
  568. /*            #define PseudoRotate(x)  ( ( (x) << 1 ) - ( (x) >> 16 ) )                                    */
  569. /*                                                                                                         */
  570. /*            for ( limit = nameLength; limit > 0; limit -= 1 ) {                                            */
  571. /*                currChar = *charPtr++;                                                                    */
  572. /*                if ( currChar == NULL ) break;                                                            */
  573. /*                length += 1;                                                                            */
  574. /*                hashValue = PseudoRotate ( hashValue ) ^ currChar;                                        */
  575. /*            }                                                                                            */
  576. /*                                                                                                         */
  577. /*            result    = (length << kPEFHashLengthShift) |                                                    */
  578. /*                      ((UInt16) ((hashValue ^ (hashValue >> 16)) & kPEFHashValueMask));                    */
  579. /*                                                                                                         */
  580. /*            return result;                                                                                */
  581. /*                                                                                                         */
  582. /*        }    // PEFComputeHashWord ()                                                                    */
  583.  
  584.  
  585.  
  586. /* =========================================================================================== */
  587. /* Exported Symbols */
  588. /* ---------------- */
  589.  
  590.  
  591.  
  592.  
  593. struct PEFExportedSymbol {                                        /* ! This structure is 10 bytes long and arrays are packed.*/
  594.     UInt32                             classAndName;                /* A combination of class and name offset.*/
  595.     UInt32                             symbolValue;                /* Typically the symbol's offset within a section.*/
  596.     SInt16                             sectionIndex;                /* The index of the section, or pseudo-section, for the symbol.*/
  597. };
  598. typedef struct PEFExportedSymbol        PEFExportedSymbol;
  599.  
  600. /* -------------------------------------------------------------------------------------------- */
  601. /* The classAndName field of the PEFExportedSymbol type has the following bit field layout.        */
  602. /*                                                                                                 */
  603. /*                                                                       3                        */
  604. /*         0             7 8                                             1                        */
  605. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  606. /*      | symbol class  | offset of symbol name in loader string table  |                        */
  607. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  608. /*        |<-- 8 bits --->|<-- 24 bits ---------------------------------->|                        */
  609.  
  610.  
  611.  
  612. enum {
  613.     kPEFExpSymClassShift        = 24,
  614.     kPEFExpSymNameOffsetMask    = 0x00FFFFFF,
  615.     kPEFExpSymMaxNameOffset        = 0x00FFFFFF                    /* 16,777,215*/
  616. };
  617.  
  618. #define PEFExportedSymbolClass(classAndName)        ((UInt8) ((classAndName) >> kPEFExpSymClassShift))
  619. #define PEFExportedSymbolNameOffset(classAndName)    ((classAndName) & kPEFExpSymNameOffsetMask)
  620.  
  621. #define PEFComposeExportedSymbol(class,nameOffset)        \
  622.             ( ( ((UInt32)(class)) << kPEFExpSymClassShift ) | ( (UInt32)(nameOffset) ) )
  623.  
  624.  
  625. enum {
  626.                                                                 /* Negative section indices indicate pseudo-sections.*/
  627.     kPEFAbsoluteExport            = -2,                            /* The symbol value is an absolute address.*/
  628.     kPEFReexportedImport        = -3                            /* The symbol value is the index of a reexported import.*/
  629. };
  630.  
  631.  
  632.  
  633.  
  634. /* =========================================================================================== */
  635. /* Loader Relocations */
  636. /* ================== */
  637.  
  638.  
  639.  
  640. /* -------------------------------------------------------------------------------------------- */
  641. /* The relocations for a section are defined by a sequence of instructions for an abstract        */
  642. /* machine that is specifically geared to performing relocations commonly needed for the "CFM"    */
  643. /* code generation model.  These instructions occur in 16 bit chunks.  Most instructions have    */
  644. /* just a single chunk.  Instructions that are larger than 16 bits have an opcode and some of    */
  645. /* the operands in the first chunk, with other operands in following chunks.                    */
  646. /*                                                                                                */
  647. /* ! Note that the multi-chunk relocations have separate "Compose" macros for each chunk.  The    */
  648. /* ! macros have the same basic name with a positional suffix of "_1st", "_2nd", etc.            */
  649.  
  650.  
  651.  
  652.  
  653. typedef UInt16                             PEFRelocChunk;
  654.  
  655. struct PEFLoaderRelocationHeader {
  656.     UInt16                             sectionIndex;                /* Index of the section to be fixed up.*/
  657.     UInt16                             reservedA;                    /* Reserved, must be zero.*/
  658.     UInt32                             relocCount;                    /* Number of 16 bit relocation chunks.*/
  659.     UInt32                             firstRelocOffset;            /* Offset of first relocation instruction.*/
  660. };
  661. typedef struct PEFLoaderRelocationHeader PEFLoaderRelocationHeader;
  662.  
  663. /* -------------------------------------------------------------------------------------------- */
  664. /* ! Note that the relocCount field is the number of 16 bit relocation chunks, i.e. 1/2 the        */
  665. /* ! total number of bytes of relocation instructions.  While most relocation instructions are    */
  666. /* ! 16 bits long, some are longer so the number of complete relocation instructions may be        */
  667. /* ! less than the relocCount value.                                                            */
  668.  
  669.  
  670.  
  671. /* ------------------------------------------------------------------------------------ */
  672. /* The PEFRelocField macro is a utility for extracting relocation instruction fields.    */
  673.  
  674.  
  675. #define PEFRFShift(offset,length)    (16 - ((offset) + (length)))
  676. #define PEFRFMask(length)            ((1 << (length)) - 1)
  677.  
  678. #define PEFRelocField(chunk,offset,length)    \
  679.             ( ( (chunk) >> (16 - ((offset) + (length))) ) & ((1 << (length)) - 1) )
  680.  
  681.  
  682.  
  683. /* =========================================================================================== */
  684. /* Basic Relocation Opcodes */
  685. /* ------------------------ */
  686.  
  687.  
  688. /* -------------------------------------------------------------------------------------------- */
  689. /* The number of opcode bits varies from 2 to 7.  The enumeration and switch table given here    */
  690. /* are defined in terms of the most significant 7 bits of the first instruction chunk.  An        */
  691. /* instruction is decoded by using the most significant 7 bits as an index into the opcode        */
  692. /* table, which in turn contains appropriately masked forms of the most significant 7 bits.        */
  693. /* The macro PEFRelocBasicOpcode assumes a declaration of the form.                                */
  694. /*                                                                                                 */
  695. /*        UInt8 kPEFRelocBasicOpcodes [kPEFRelocBasicOpcodeRange] = { PEFMaskedBasicOpcodes };    */
  696.  
  697.  
  698.  
  699. enum {
  700.     kPEFRelocBasicOpcodeRange    = 128
  701. };
  702.  
  703. #define PEFRelocBasicOpcode(firstChunk) (kPEFRelocBasicOpcodes[(firstChunk)>>9])
  704.  
  705.  
  706.  
  707. /* -------------------------------------------------------------------------------------------- */
  708. /* The relocation opcodes, clustered by major and minor groups.  The instructions within a        */
  709. /* cluster all have the same bit field layout.  The enumeration values use the high order 7        */
  710. /* bits of the relocation instruction.  Unused low order bits are set to zero.                    */
  711.  
  712.  
  713. enum {
  714.     kPEFRelocBySectDWithSkip    = 0x00,                            /* Binary: 00x_xxxx*/
  715.     kPEFRelocBySectC            = 0x20,                            /* Binary: 010_0000, group is "RelocRun"*/
  716.     kPEFRelocBySectD            = 0x21,                            /* Binary: 010_0001*/
  717.     kPEFRelocTVector12            = 0x22,                            /* Binary: 010_0010*/
  718.     kPEFRelocTVector8            = 0x23,                            /* Binary: 010_0011*/
  719.     kPEFRelocVTable8            = 0x24,                            /* Binary: 010_0100*/
  720.     kPEFRelocImportRun            = 0x25,                            /* Binary: 010_0101*/
  721.     kPEFRelocSmByImport            = 0x30,                            /* Binary: 011_0000, group is "RelocSmIndex"*/
  722.     kPEFRelocSmSetSectC            = 0x31,                            /* Binary: 011_0001*/
  723.     kPEFRelocSmSetSectD            = 0x32,                            /* Binary: 011_0010*/
  724.     kPEFRelocSmBySection        = 0x33,                            /* Binary: 011_0011*/
  725.     kPEFRelocIncrPosition        = 0x40,                            /* Binary: 100_0xxx*/
  726.     kPEFRelocSmRepeat            = 0x48,                            /* Binary: 100_1xxx*/
  727.     kPEFRelocSetPosition        = 0x50,                            /* Binary: 101_000x*/
  728.     kPEFRelocLgByImport            = 0x52,                            /* Binary: 101_001x*/
  729.     kPEFRelocLgRepeat            = 0x58,                            /* Binary: 101_100x*/
  730.     kPEFRelocLgSetOrBySection    = 0x5A,                            /* Binary: 101_101x*/
  731.     kPEFRelocUndefinedOpcode    = 0xFF                            /* Used in masking table for all undefined values.*/
  732. };
  733.  
  734.  
  735.  
  736. /* ----------------------------------------------------------------------------    */
  737. /* The RelocLgSetOrBySection instruction has an additional 4 bits of subopcode    */
  738. /* beyond the 7 used by the dispatch table.  To be precise it has 6 plus 4 but    */
  739. /* the dispatch table ignores the 7th bit, so the subdispatch is on all 4 extra    */
  740. /* subopcode bits.                                                                */
  741.  
  742.  
  743. enum {
  744.     kPEFRelocLgBySectionSubopcode = 0x00,                        /* Binary: 0000*/
  745.     kPEFRelocLgSetSectCSubopcode = 0x01,                        /* Binary: 0001*/
  746.     kPEFRelocLgSetSectDSubopcode = 0x02                            /* Binary: 0010*/
  747. };
  748.  
  749. #define PEFRelocLgSetOrBySubopcode(chunk) (((chunk) >> 6) & 0x0F)
  750.  
  751.  
  752.  
  753. /* -------------------------------------------------------------------------------------------- */
  754. /* The initial values for the opcode "masking" table.  This has the enumeration values from        */
  755. /* above with appropriate replications for "don't care" bits.  It is almost certainly shorter    */
  756. /* and faster to look up the masked value in a table than to use a branch tree.                    */
  757.  
  758.  
  759. #define PEFMaskedBasicOpcodes                                                                                                                    \
  760.                                                                                                                                                 \
  761.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x00 .. 0x03 */    \
  762.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x04 .. 0x07 */    \
  763.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x08 .. 0x0B */    \
  764.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x0C .. 0x0F */    \
  765.                                                                                                                                                 \
  766.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x10 .. 0x13 */    \
  767.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x14 .. 0x17 */    \
  768.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x18 .. 0x1B */    \
  769.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x1C .. 0x1F */    \
  770.                                                                                                                                                 \
  771.             kPEFRelocBySectC,            kPEFRelocBySectD,            kPEFRelocTVector12,            kPEFRelocTVector8,            /* 0x20 .. 0x23 */    \
  772.             kPEFRelocVTable8,            kPEFRelocImportRun,            kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x24 .. 0x27 */    \
  773.                                                                                                                                                 \
  774.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x28 .. 0x2B */    \
  775.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x2C .. 0x2F */    \
  776.                                                                                                                                                 \
  777.             kPEFRelocSmByImport,        kPEFRelocSmSetSectC,        kPEFRelocSmSetSectD,        kPEFRelocSmBySection,        /* 0x30 .. 0x33 */    \
  778.                                                                                                                                                 \
  779.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x34 .. 0x37 */    \
  780.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x38 .. 0x3B */    \
  781.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x3C .. 0x3F */    \
  782.                                                                                                                                                 \
  783.             kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        /* 0x40 .. 0x43 */    \
  784.             kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        /* 0x44 .. 0x47 */    \
  785.                                                                                                                                                 \
  786.             kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            /* 0x48 .. 0x4B */    \
  787.             kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            /* 0x4C .. 0x4F */    \
  788.                                                                                                                                                 \
  789.             kPEFRelocSetPosition,        kPEFRelocSetPosition,        kPEFRelocLgByImport,        kPEFRelocLgByImport,        /* 0x50 .. 0x53 */    \
  790.                                                                                                                                                 \
  791.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x54 .. 0x57 */    \
  792.                                                                                                                                                 \
  793.             kPEFRelocLgRepeat,            kPEFRelocLgRepeat,            kPEFRelocLgSetOrBySection,    kPEFRelocLgSetOrBySection,    /* 0x58 .. 0x5B */    \
  794.                                                                                                                                                 \
  795.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x5C .. 0x5F */    \
  796.                                                                                                                                                 \
  797.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x60 .. 0x63 */    \
  798.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x64 .. 0x67 */    \
  799.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x68 .. 0x6B */    \
  800.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x6C .. 0x6F */    \
  801.                                                                                                                                                 \
  802.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x70 .. 0x73 */    \
  803.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x74 .. 0x77 */    \
  804.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x78 .. 0x7B */    \
  805.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode    /* 0x7C .. 0x7F */
  806.  
  807.  
  808.  
  809. /* =========================================================================================== */
  810. /* RelocBySectDWithSkip Instruction */
  811. /* -------------------------------- */
  812.  
  813.  
  814.  
  815. /* -------------------------------------------------------------------------------------------- */
  816. /* The "RelocBySectDWithSkip" instruction has the following bit field layout.                    */
  817. /*                                                                                                 */
  818. /*                             1         1                                                        */
  819. /*         0 1 2             9 0         5                                                        */
  820. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  821. /*        |0 0| skip count    | rel count |                                                        */
  822. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  823. /*        | 2 |<-- 8 bits --->|<--  6 --->|                                                        */
  824. /*                                                                                                 */
  825. /* ! Note that the stored skip count and reloc count are the actual values!                        */
  826.  
  827.  
  828. enum {
  829.     kPEFRelocWithSkipMaxSkipCount = 255,
  830.     kPEFRelocWithSkipMaxRelocCount = 63
  831. };
  832.  
  833. #define PEFRelocWithSkipSkipCount(chunk)    PEFRelocField ( (chunk), 2, 8 )
  834. #define PEFRelocWithSkipRelocCount(chunk)    PEFRelocField ( (chunk), 10, 6 )
  835.  
  836. #define PEFRelocComposeWithSkip(skipCount,relocCount)    \
  837.             ( 0x0000 | (((UInt16)(skipCount)) << 6) | ((UInt16)(relocCount)) )
  838.  
  839.  
  840.  
  841. /* =========================================================================================== */
  842. /* RelocRun Group */
  843. /* -------------- */
  844.  
  845.  
  846.  
  847. /* -------------------------------------------------------------------------------------------- */
  848. /* The "RelocRun" group includes the "RelocBySectC", "RelocBySectD", "RelocTVector12",            */
  849. /* "RelocTVector8", "RelocVTable8", and "RelocImportRun" instructions.  This group has the        */
  850. /* following bit field layout.                                                                    */
  851. /*                                                                                                 */
  852. /*                                       1                                                        */
  853. /*         0   2 3     6 7               5                                                        */
  854. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  855. /*        |0 1 0| subop.| run length      |                                                        */
  856. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  857. /*        |  3  |<- 4 ->|<-- 9 bits ----->|                                                        */
  858. /*                                                                                                 */
  859. /* ! Note that the stored run length is the actual value minus 1, but the macros deal with the    */
  860. /* ! actual value!                                                                                */
  861.  
  862.  
  863. enum {
  864.     kPEFRelocRunMaxRunLength    = 512
  865. };
  866.  
  867. #define PEFRelocRunSubopcode(chunk)    PEFRelocField ( (chunk), 3, 4 )
  868. #define PEFRelocRunRunLength(chunk)    (PEFRelocField ( (chunk), 7, 9 ) + 1)
  869.  
  870. #define PEFRelocComposeRun(subopcode,runLength)    \
  871.             ( 0x4000 | (((UInt16)(subopcode)) << 9) | ((UInt16)((runLength)-1)) )
  872.  
  873. #define PEFRelocComposeBySectC(runLength)        PEFRelocComposeRun ( 0, (runLength) )
  874. #define PEFRelocComposeBySectD(runLength)        PEFRelocComposeRun ( 1, (runLength) )
  875. #define PEFRelocComposeTVector12(runLength)        PEFRelocComposeRun ( 2, (runLength) )
  876. #define PEFRelocComposeTVector8(runLength)        PEFRelocComposeRun ( 3, (runLength) )
  877. #define PEFRelocComposeVTable8(runLength)        PEFRelocComposeRun ( 4, (runLength) )
  878. #define PEFRelocComposeImportRun(runLength)        PEFRelocComposeRun ( 5, (runLength) )
  879.  
  880.  
  881.  
  882. /* =========================================================================================== */
  883. /* RelocSmIndex Group */
  884. /* ------------------ */
  885.  
  886.  
  887.  
  888. /* ----------------------------------------------------------------------------------------    */
  889. /* The "RelocSmIndex" group includes the "RelocSmByImport", "RelocSmSetSectC",                */
  890. /* "RelocSmSetSectD" and "RelocSmBySection" instructions.  This group has the following bit    */
  891. /* field layout.                                                                            */
  892. /*                                                                                             */
  893. /*                                       1                                                    */
  894. /*         0   2 3     6 7               5                                                    */
  895. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                    */
  896. /*        |0 1 1| subop.| index           |                                                    */
  897. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                    */
  898. /*        |  3  |<- 4 ->|<-- 9 bits ----->|                                                    */
  899. /*                                                                                             */
  900. /* ! Note that the stored index is the actual value!                                        */
  901.  
  902.  
  903. enum {
  904.     kPEFRelocSmIndexMaxIndex    = 511
  905. };
  906.  
  907. #define PEFRelocSmIndexSubopcode(chunk)    PEFRelocField ( (chunk), 3, 4 )
  908. #define PEFRelocSmIndexIndex(chunk)        PEFRelocField ( (chunk), 7, 9 )
  909.  
  910. #define PEFRelocComposeSmIndex(subopcode,index)    \
  911.             ( 0x6000 | (((UInt16)(subopcode)) << 9) | ((UInt16)(index)) )
  912.  
  913. #define PEFRelocComposeSmByImport(index)    PEFRelocComposeSmIndex ( 0, (index) )
  914. #define PEFRelocComposeSmSetSectC(index)    PEFRelocComposeSmIndex ( 1, (index) )
  915. #define PEFRelocComposeSmSetSectD(index)    PEFRelocComposeSmIndex ( 2, (index) )
  916. #define PEFRelocComposeSmBySection(index)    PEFRelocComposeSmIndex ( 3, (index) )
  917.  
  918.  
  919.  
  920. /* =========================================================================================== */
  921. /* RelocIncrPosition Instruction */
  922. /* ----------------------------- */
  923.  
  924.  
  925.  
  926. /* -------------------------------------------------------------------------------------------- */
  927. /* The "RelocIncrPosition" instruction has the following bit field layout.                        */
  928. /*                                                                                                 */
  929. /*                                       1                                                        */
  930. /*         0     3 4                     5                                                        */
  931. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  932. /*        |1 0 0 0| offset                |                                                        */
  933. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  934. /*        |<- 4 ->|<-- 12 bits ---------->|                                                        */
  935. /*                                                                                                 */
  936. /* ! Note that the stored offset is the actual value minus 1, but the macros deal with the        */
  937. /* ! actual value!                                                                                */
  938.  
  939.  
  940. enum {
  941.     kPEFRelocIncrPositionMaxOffset = 4096
  942. };
  943.  
  944. #define PEFRelocIncrPositionOffset(chunk)    (PEFRelocField ( (chunk), 4, 12 ) + 1)
  945.  
  946. #define PEFRelocComposeIncrPosition(offset)    \
  947.             ( 0x8000 | ((UInt16)((offset)-1)) )
  948.  
  949.  
  950.  
  951. /* =========================================================================================== */
  952. /* RelocSmRepeat Instruction */
  953. /* ------------------------- */
  954.  
  955.  
  956.  
  957. /* -------------------------------------------------------------------------------------------- */
  958. /* The "RelocSmRepeat" instruction has the following bit field layout.                            */
  959. /*                                                                                                 */
  960. /*                                       1                                                        */
  961. /*         0     3 4     7 8             5                                                        */
  962. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  963. /*        |1 0 0 1| chnks | repeat count  |                                                        */
  964. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  965. /*        |<- 4 ->|<- 4 ->|<-- 8 bits --->|                                                        */
  966. /*                                                                                                 */
  967. /* ! Note that the stored chunk count and repeat count are the actual values minus 1, but the    */
  968. /* ! macros deal with the actual values!                                                        */
  969.  
  970.  
  971. enum {
  972.     kPEFRelocSmRepeatMaxChunkCount = 16,
  973.     kPEFRelocSmRepeatMaxRepeatCount = 256
  974. };
  975.  
  976. #define PEFRelocSmRepeatChunkCount(chunk)    (PEFRelocField ( (chunk), 4, 4 ) + 1)
  977. #define PEFRelocSmRepeatRepeatCount(chunk)    (PEFRelocField ( (chunk), 8, 8 ) + 1)
  978.  
  979. #define PEFRelocComposeSmRepeat(chunkCount,repeatCount)    \
  980.             ( 0x9000 | ((((UInt16)(chunkCount))-1) << 8) | (((UInt16)(repeatCount))-1) )
  981.  
  982.  
  983.  
  984. /* =========================================================================================== */
  985. /* RelocSetPosition Instruction */
  986. /* ---------------------------- */
  987.  
  988.  
  989.  
  990. /* -------------------------------------------------------------------------------------------- */
  991. /* The "RelocSetPosition" instruction has the following bit field layout.                        */
  992. /*                                                                                                 */
  993. /*                                       1                                   1                    */
  994. /*         0         5 6                 5     0                             5                    */
  995. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  996. /*        |1 0 1 0 0 0| offset (high)     |   | offset (low)                  |                    */
  997. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  998. /*        |<-- 6 ---->|<-- 10 bits ------>|   |<-- 16 bits ------------------>|                    */
  999. /*                                                                                                 */
  1000. /* ! Note that the stored offset is the actual value!                                            */
  1001.  
  1002.  
  1003. enum {
  1004.     kPEFRelocSetPosMaxOffset    = 0x03FFFFFF                    /* 67,108,863*/
  1005. };
  1006.  
  1007. #define PEFRelocSetPosOffsetHigh(chunk)    PEFRelocField ( (chunk), 6, 10 )
  1008.  
  1009. #define PEFRelocSetPosFullOffset(firstChunk,secondChunk)    \
  1010.             ( ((((UInt32)(firstChunk)) & 0x03FF) << 16) | ((UInt32)(secondChunk)) )
  1011.  
  1012. #define PEFRelocComposeSetPosition_1st(fullOffset)    \
  1013.             ( 0xA000 | ((UInt16) (((UInt32)(fullOffset)) >> 16) ) )
  1014. #define PEFRelocComposeSetPosition_2nd(fullOffset)    \
  1015.             ( (UInt16) ((UInt32)(fullOffset) & 0xFFFF) )
  1016.  
  1017.  
  1018.  
  1019. /* =========================================================================================== */
  1020. /* RelocLgByImport Instruction */
  1021. /* --------------------------- */
  1022.  
  1023.  
  1024.  
  1025. /* -------------------------------------------------------------------------------------------- */
  1026. /* The "RelocLgByImport" instruction has the following bit field layout.                        */
  1027. /*                                                                                                 */
  1028. /*                                       1                                   1                    */
  1029. /*         0         5 6                 5     0                             5                    */
  1030. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  1031. /*        |1 0 1 0 0 1| index (high)      |   | index (low)                   |                    */
  1032. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  1033. /*        |<-- 6 ---->|<-- 10 bits ------>|   |<-- 16 bits ------------------>|                    */
  1034. /*                                                                                                 */
  1035. /* ! Note that the stored offset is the actual value!                                            */
  1036.  
  1037.  
  1038. enum {
  1039.     kPEFRelocLgByImportMaxIndex    = 0x03FFFFFF                    /* 67,108,863*/
  1040. };
  1041.  
  1042. #define PEFRelocLgByImportIndexHigh(chunk)    PEFRelocField ( (chunk), 6, 10 )
  1043.  
  1044. #define PEFRelocLgByImportFullIndex(firstChunk,secondChunk)    \
  1045.             ( ((((UInt32)(firstChunk)) & 0x03FF) << 16) | ((UInt32)(secondChunk)) )
  1046.  
  1047. #define PEFRelocComposeLgByImport_1st(fullIndex)    \
  1048.             ( 0xA400 | ((UInt16) (((UInt32)(fullIndex)) >> 16) ) )
  1049. #define PEFRelocComposeLgByImport_2nd(fullIndex)    \
  1050.             ( (UInt16) ((UInt32)(fullIndex) & 0xFFFF) )
  1051.  
  1052.  
  1053.  
  1054. /* =========================================================================================== */
  1055. /* RelocLgRepeat Instruction */
  1056. /* ------------------------- */
  1057.  
  1058.  
  1059.  
  1060. /* -------------------------------------------------------------------------------------------- */
  1061. /* The "RelocLgRepeat" instruction has the following bit field layout.                            */
  1062. /*                                                                                                 */
  1063. /*                             1         1                                   1                    */
  1064. /*         0         5 6     9 0         5     0                             5                    */
  1065. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  1066. /*        |1 0 1 1 0 0| chnks | rpt (high)|   | repeat count (low)            |                    */
  1067. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  1068. /*        |<--  6 --->|<- 4 ->|<--  6 --->|   |<-- 16 bits ------------------>|                    */
  1069. /*                                                                                                 */
  1070. /* ! Note that the stored chunk count is the actual value minus 1, but the macros deal with        */
  1071. /* ! the actual value!  The stored repeat count is the actual value!                            */
  1072.  
  1073.  
  1074. enum {
  1075.     kPEFRelocLgRepeatMaxChunkCount = 16,
  1076.     kPEFRelocLgRepeatMaxRepeatCount = 0x003FFFFF                /* 4,194,303*/
  1077. };
  1078.  
  1079. #define PEFRelocLgRepeatChunkCount(chunk)        (PEFRelocField ( (chunk), 6, 4 ) + 1)
  1080. #define PEFRelocLgRepeatRepeatCountHigh(chunk)    PEFRelocField ( (chunk), 10, 6 )
  1081.  
  1082. #define PEFRelocLgRepeatFullRepeatCount(firstChunk,secondChunk)    \
  1083.             ( ((((UInt32)(firstChunk)) & 0x003F) << 16) | ((UInt32)(secondChunk)) )
  1084.  
  1085. #define PEFRelocComposeLgRepeat_1st(chunkCount,fullRepeatCount)    \
  1086.             ( 0xB000 | ((((UInt16)(chunkCount))-1) << 6) | ((UInt16) (((UInt32)(fullRepeatCount)) >>16 ) ) )
  1087. #define PEFRelocComposeLgRepeat_2nd(chunkCount,fullRepeatCount)    \
  1088.             ( (UInt16) ((UInt32)(fullRepeatCount) & 0xFFFF) )
  1089.  
  1090.  
  1091.  
  1092. /* =========================================================================================== */
  1093. /* RelocLgSetOrBySection Group */
  1094. /* --------------------------- */
  1095.  
  1096.  
  1097.  
  1098. /* -------------------------------------------------------------------------------------------- */
  1099. /* The "RelocLgSetOrBySection" instruction is really a group including the "RelocLgBySection",    */
  1100. /* "RelocLgSetSectC" and "RelocLgSetSectD" instructions.  This group has the following bit        */
  1101. /* field layout.                                                                                */
  1102. /*                                                                                                 */
  1103. /*                             1         1                                   1                    */
  1104. /*         0         5 6     9 0         5     0                             5                    */
  1105. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  1106. /*        |1 0 1 1 0 1| subop | idx (high)|   | index (low)                   |                    */
  1107. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  1108. /*        |<--  6 --->|<- 4 ->|<--  6 --->|   |<-- 16 bits ------------------>|                    */
  1109. /*                                                                                                 */
  1110. /* ! Note that the stored index is the actual value!                                            */
  1111.  
  1112.  
  1113. enum {
  1114.     kPEFRelocLgSetOrBySectionMaxIndex = 0x003FFFFF                /* 4,194,303*/
  1115. };
  1116.  
  1117. #define PEFRelocLgSetOrBySectionSubopcode(chunk)    PEFRelocField ( (chunk), 6, 4 )
  1118. #define PEFRelocLgSetOrBySectionIndexHigh(chunk)    PEFRelocField ( (chunk), 10, 6 )
  1119.  
  1120. #define PEFRelocLgSetOrBySectionFullIndex(firstChunk,secondChunk)    \
  1121.             ( ((((UInt32)(firstChunk)) & 0x003F) << 16) | ((UInt32)(secondChunk)) )
  1122.  
  1123. #define PEFRelocComposeLgSetOrBySection_1st(subopcode,fullIndex)    \
  1124.             ( 0xB400 | (((UInt16)(subopcode)) << 6) | ((UInt16) (((UInt32)(fullIndex)) >> 16) ) )
  1125. #define PEFRelocComposeLgSetOrBySection_2nd(subopcode,fullIndex)    \
  1126.             ( (UInt16) ((UInt32)(fullIndex) & 0xFFFF) )
  1127.  
  1128. #define PEFRelocComposeLgBySection(fullIndex)    PEFRelocComposeLgSetOrBySection ( 0x00, (fullIndex) )
  1129. #define PEFRelocComposeLgSetSectC(fullIndex)    PEFRelocComposeLgSetOrBySection ( 0x01, (fullIndex) )
  1130. #define PEFRelocComposeLgSetSectD(fullIndex)    PEFRelocComposeLgSetOrBySection ( 0x02, (fullIndex) )
  1131.  
  1132.  
  1133.  
  1134. #if PRAGMA_STRUCT_ALIGN
  1135.     #pragma options align=reset
  1136. #elif PRAGMA_STRUCT_PACKPUSH
  1137.     #pragma pack(pop)
  1138. #elif PRAGMA_STRUCT_PACK
  1139.     #pragma pack()
  1140. #endif
  1141.  
  1142. #ifdef PRAGMA_IMPORT_OFF
  1143. #pragma import off
  1144. #elif PRAGMA_IMPORT
  1145. #pragma import reset
  1146. #endif
  1147.  
  1148. #ifdef __cplusplus
  1149. }
  1150. #endif
  1151.  
  1152. #endif /* __PEFBINARYFORMAT__ */
  1153.  
  1154.